package mt.dummy;

import java.util.ArrayList;
import java.util.HashMap;

import mt.Order;
import mt.comm.ServerComm;
import mt.comm.ServerMessage;
import mt.comm.ServerSideMessage;
import mt.server.MicroTraderServer;

public class MicroTraderServerDummy implements MicroTraderServer {

	private HashMap<Integer,Order> clientsOrders = new HashMap<Integer,Order>();
	private ArrayList<String> clients = new ArrayList<String>();
	private int currentOrderID;
	private boolean serverUp;

	public void serverDown() {
		serverUp = false;
	}

	@Override
	public void start(ServerComm serverComm) {
		serverComm.start();
		currentOrderID = 0;
		serverUp = true;
		while(serverUp) {
			if(serverComm.hasNextMessage()) {
				ServerMessage message = (ServerMessage) serverComm.getNextMessage();
				if(message.getType().equals(ServerMessage.Type.NEW_ORDER)) {
					Order order = message.getOrder();
					order.setServerOrderID(currentOrderID);
					clientsOrders.put(currentOrderID,order);
					for(String client : clients) {
						serverComm.sendOrder(client,order);
					}
					if(order.isBuyOrder()) {
						for(int i = 0; i < currentOrderID; i++) {
							if((clientsOrders.get(i).isSellOrder()) &&
									(clientsOrders.get(i).equals(order.getStock()) &&
											(order.getPricePerUnit() >= clientsOrders.get(i).getPricePerUnit()))) {
								if(order.getNumberOfUnits() < clientsOrders.get(i).getNumberOfUnits()) {
									//venda parcial -> reduz numero na venda
									//compra total -> delete compra
									clientsOrders.get(i).setNumberOfUnits(
											clientsOrders.get(i).getNumberOfUnits() - order.getNumberOfUnits());
									order.setNumberOfUnits(0);
									clientsOrders.remove(currentOrderID);
								} else {
									//venda total -> delete na venda
									//compra parcial -> reduz numero na compra
									order.setNumberOfUnits(
											order.getNumberOfUnits() - clientsOrders.get(i).getNumberOfUnits());
									clientsOrders.get(i).setNumberOfUnits(0);
									for(String client : clients) {
										serverComm.sendOrder(client,order);
										serverComm.sendOrder(client,clientsOrders.get(i));										
									}
									clientsOrders.remove(i);
								}
							}
						}
					} else if(order.isSellOrder()) {
						for(int i = 0; i < currentOrderID; i++) {
							if((clientsOrders.get(i).isBuyOrder()) &&
									(clientsOrders.get(i).equals(order.getStock()) &&
											(order.getPricePerUnit() <= clientsOrders.get(i).getPricePerUnit()))) {
								if(order.getNumberOfUnits() < clientsOrders.get(i).getNumberOfUnits()) {
									//compra parcial -> reduz numero na compra
									//venda total -> delete venda
									clientsOrders.get(i).setNumberOfUnits(
											clientsOrders.get(i).getNumberOfUnits() - order.getNumberOfUnits());
									order.setNumberOfUnits(0);
									clientsOrders.remove(currentOrderID);	
								} else {
									//compra total -> delete na compra
									//venda parcial -> reduz numero na venda
									order.setNumberOfUnits(
											order.getNumberOfUnits() - clientsOrders.get(i).getNumberOfUnits());
									clientsOrders.get(i).setNumberOfUnits(0);
									for(String client : clients) {
										serverComm.sendOrder(client,order);
										serverComm.sendOrder(client,clientsOrders.get(i));										
									}
									clientsOrders.remove(i);	
								}
							}
						}
					}
					currentOrderID++;
				} else if(message.getType().equals(ServerSideMessage.Type.CONNECTED)) {
					clients.add(message.getSenderNickname());
					for(int i = 0; i < currentOrderID; i++) {
						serverComm.sendOrder(message.getSenderNickname(), clientsOrders.get(i));
					}
				} else if(message.getType().equals(ServerSideMessage.Type.DISCONNECTED)) {
					clients.remove(message.getSenderNickname());
					for(int i = 0; i < currentOrderID; i++) {
						if(clientsOrders.get(i).getNickname().equals(message.getSenderNickname())) {
							clientsOrders.remove(i);
						}
					}
				}
			}
		}
	}
}
